//
// unload.cpp
// unload
// unloads data from an application database into the unload.<applnbr> file
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#include "../SDK/ToolsInterface.h"
#include "../defns.h"
using namespace ProteaApp1;

long APPLICATION = 0;

class XCExtractInterface : public XCAppInterface {
public:
	void ExtractData( XCFileTransport* output ) {
		INFUNC( XCExtractInterface::ExtractData, this );

		XCSQLGen query( this );
		XCDBStatement* stmt;
		XCTxn* txn;
		XCCompare comp;
		char temp[ 256 ];

		int count = appdic_header->db_tables.count;
		buffer_db_tables* table = (buffer_db_tables*)(APPDIC_DATA + appdic_header->db_tables.offset);

		txn = GetDatabase()->CreateTxn( NULL );

		sprintf( temp, "<Application Number=\"%ld\">\n", APPLICATION );
		output->Send( temp );

		while (count) {
			buffer_format* format = (buffer_format*)(APPDIC_DATA + table->format);

			printf( "Dumping table: %s\n", format->name );

			XCBuffer* buf = CreateBuffer( format->number );
			assert( buf );

			sprintf( temp, "\t<Buffer Name=\"%s\" Number=\"%ld\">\n", format->real_name, format->number );
			output->Send( temp );

			// Output the buffer structure
			output->Send( "\t\t<STRUCTURE>\n" );
			for (int i=0; i<buf->GetFieldCount(); i++) {
				XCField* field = buf->GetFieldByIndex( i );

				sprintf(
					temp,
					"\t\t\t<Field Name=\"%s\" Number=\"%ld\" Type=\"%d\" Length=\"%ld\" Default=\"\" Dec_Places=\"%ld\" Flags=\"%d\"/>\n",
					field->GetFieldName(),
					field->GetFieldNumber(),
					field->GetType(),
					field->GetLength(),
					field->GetDecPlaces(),
					field->GetFlags() );
				output->Send( temp );
			};
			output->Send( "\t\t</STRUCTURE>\n" );


			// Query for all records
			query.MakeSELECT( buf );
			stmt = txn->ExecuteSQL( &query );

			// Output each record found
			while (!stmt->Eof()) {
				output->Send( "\t\t<RECORD>\n" );

				for (int i=0; i<buf->GetFieldCount(); i++) {
					XCField* field = buf->GetFieldByIndex( i );
					sprintf( temp, "\t\t\t<Field Name=\"%s\">", field->GetFieldName() );
					output->Send( temp );

					field->OutputTransport( output, temp );
					output->Send( "</Field>\n" );
				};	// for
				output->Send( "\t\t</RECORD>\n" );
				stmt->MoveNext();
			};
			stmt->Release();
			output->Send( "\t</Buffer>\n\n" );

			buf->Release();

			table++;
			count--;
		};	// while count

		output->Send( "</Application>" );

		txn->EndTxn( false );

		OUTFUNC();
	};
};



int main(int argc, char* argv[]) {
	XCExtractInterface extract;
	XCAppOptions myopts;

	Protea::ShowIntro( "unload" );

	if (argc > 1 && !strcmp(argv[1],"-L"))
	{
		Protea::ShowLicense();
		return 0;
	};

	if (argc != 2) {
		cout << "Usage: unload [ApplicationNumber]" << endl;
		return 1;
	};

	// Obtain the application number
	APPLICATION = atoi( argv[1] );
	if (APPLICATION < 2) {
		cout << "Invalid application number" << endl;
		return 1;
	};

	XCFileTransport file( NULL );
	try {
		Protea::Initialize();

		extract.GetOptions( myopts );
		myopts.debug_level_cutoff[ TCL_APPINTERFACE ] = TLV_MEDIUM;
//		myopts.debug_type_filter = TRC_APPINTERFACE | TRC_DATABASE;
		myopts.debug_type_filter = 0;
		myopts.no_transactions = true;
		extract.SetOptions( myopts );
		extract.Initialize( "unload", APPLICATION );

		printf( "SECURITY CHECK\n" );
		DO_DEVTOOL_SECURITY_CHECK;
		printf( "DONE\n" );

		char tempfile[ 255 ];
		sprintf( tempfile, "unload.%ld", APPLICATION );
		file.Open( tempfile, read_write, create_always );
		file.Send( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" );
		extract.ExtractData( &file );
	} catch( XCToolsError& error ) {
		XCOutputCallStack( &extract, error.GetErrorNumber(),error.GetDescription() );
	} catch( ... ) {
		XCOutputCallStack( &extract, -1, NULL );
	};

	file.Close();

	Protea::Uninitialize();

	return 0;
};
